package dict

import (
	"context"
	"gitee.com/igolang/imoney/internal/common/constants"
	"gitee.com/igolang/imoney/internal/common/keys"
	"gitee.com/igolang/imoney/internal/core/client"
	"gitee.com/igolang/imoney/internal/models/dao"
	"gitee.com/igolang/imoney/internal/models/model"
	"gitee.com/igolang/pkg/xjson"
	"github.com/redis/go-redis/v9"
	"time"
)

var DictData = &dictData{}

type dictData struct{}

func (s *dictData) Get(t string) ([]*model.SysDictDatum, error) {
	rc := client.Redis()
	key := keys.DictData(t)
	b, err := rc.Get(context.Background(), key.Key).Bytes()
	if err != nil && err != redis.Nil {
		return nil, err
	}
	list := make([]*model.SysDictDatum, 0)
	if xjson.Unmarshal(b, &list) == nil {
		return list, nil
	}

	list = s.SetCache(t)
	return list, nil
}

func (s *dictData) Value(t, label string) string {
	rows, _ := s.Get(t)
	if len(rows) == 0 {
		return ""
	}

	return s.ValueOptions(rows, label)
}

func (s *dictData) ValueOptions(rows []*model.SysDictDatum, label string) string {
	if len(rows) == 0 {
		return ""
	}
	for _, v := range rows {
		if v.DictLabel == label {
			return v.DictValue
		}
	}

	return ""
}

func (s *dictData) Label(t, value string) string {
	rows, _ := s.Get(t)
	if len(rows) == 0 {
		return ""
	}

	return s.LabelOptions(rows, value)
}

func (s *dictData) LabelOptions(rows []*model.SysDictDatum, value string) string {
	if len(rows) == 0 {
		return ""
	}
	for _, v := range rows {
		if v.DictValue == value {
			return v.DictLabel
		}
	}

	return ""
}

func (s *dictData) SetCache(t string) []*model.SysDictDatum {
	rows, _ := dao.SysDictDatum.Where(dao.SysDictDatum.DictType.Eq(t), dao.SysDictDatum.Status.Eq(constants.SystemOkStatus)).Find()
	if len(rows) == 0 {
		rows = make([]*model.SysDictDatum, 0)
	}

	key := keys.DictData(t)
	b, _ := xjson.Marshal(rows)
	expired := key.Expire
	if len(rows) == 0 { // 空的时候也给一个缓存，防止穿透
		expired = 5 * time.Second
	}
	client.Redis().Set(context.Background(), key.Key, b, expired)
	return rows
}

func (s *dictData) CleanCache(t string) {
	key := keys.DictData(t)
	client.Redis().Del(context.Background(), key.Key)
}
